import {
  base64ToFile,
  compressImage,
  createResolvablePromise,
  UUID,
} from '@/utils/common'
import { showToast } from '@/utils/toast'
import {
  Button,
  Input,
  Modal,
  ModalBody,
  ModalContent,
  ModalFooter,
  ModalHeader,
  Textarea,
  useDisclosure,
} from '@heroui/react'
import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
import '../scss/AddGameModal.scss'
import ImageSelect from '@/components/ImageSelect'
import RadioGroup from '@/components/RadioGroup'
import { open } from '@tauri-apps/plugin-dialog'
import AddSvg from '@/svg/AddSvg'
import RemoveSvg from '@/svg/RemoveSvg'
import { Game, PrevieMedia } from '@/type'
import { gameStore } from '@/store/gameStore'
import FileSaveManager from '@/lib/FileSaveManager'
interface Props {}

type ResolveType = {}

const defaultForm = {
  name: '',
  description: '',
  cover: null as string,
  thumb: null as string,
  openMode: 'file' as 'file' | 'cmd',
  openCmd: '',
  openFilePath: '',
  previeMedia: [] as {
    type: 'image' | 'video'
    file: File
    tmpUrl: string
  }[],
}

const title = '添加游戏'
const AddGameModal = (_props: Props, ref: any) => {
  const { isOpen, onOpen, onClose } = useDisclosure()

  const [loading, setLoading] = useState(false)
  const successResolve =
    useRef<(value: ResolveType | PromiseLike<ResolveType>) => void>(null)
  const previewMultiRef = useRef(null)
  useImperativeHandle(ref, () => ({
    show: () => {
      const [p, resolve] = createResolvablePromise<ResolveType>()
      successResolve.current = resolve
      onOpen()
      return p
    },
  }))

  function verify() {
    if (!form.name) {
      showToast('请输入游戏名称')
      return false
    }
    if (!form.cover) {
      showToast('请选择竖屏封面图')
      return false
    }
    if (!form.thumb) {
      showToast('请选择横屏封面图')
      return false
    }
    if (form.openMode == 'file' && !form.openFilePath) {
      showToast('请选择启动文件路径')
      return false
    } else if (form.openMode == 'cmd' && !form.openCmd) {
      showToast('请输入启动命令')
      return false
    }
    return true
  }
  const onSubmit = async () => {
    const data: ResolveType = {}
    successResolve.current(data)

    if (!verify()) return
    setLoading(true)
    const previeMedia: PrevieMedia[] = []
    try {
      for (let i = 0; i < form.previeMedia.length; i++) {
        const item = form.previeMedia[i]
        const localFile = await FileSaveManager.saveFileToUrl(
          item.file,
          'previewMedia'
        )
        previeMedia.push({
          type: item.type,
          data: localFile,
        })
      }
      const params: Game = {
        id: UUID(),
        name: form.name,
        description: form.description,
        cover: await FileSaveManager.saveFileToUrl(
          await compressImage(base64ToFile(form.cover, 'image.png'), 460),
          'cover'
        ),
        thumb: await FileSaveManager.saveFileToUrl(
          base64ToFile(form.thumb, 'image.png'),
          'thumb'
        ),
        openMode: form.openMode,
        openCmd: form.openCmd,
        openFilePath: form.openFilePath,
        previeMedia,
        createTime: new Date().getTime(),
      }
      gameStore.setValue('games', [params, ...gameStore.value.games])

      setForm(defaultForm)
    } catch {
      showToast('添加失败')
      return
    } finally {
      setLoading(false)
    }

    onClose()
    showToast('添加成功')
  }

  const [form, setForm] = useState(defaultForm)

  return (
    <Modal
      scrollBehavior="inside"
      isOpen={isOpen}
      onClose={onClose}
      className="dark AddGameModal"
      isDismissable={false}
      size="4xl">
      <ModalContent>
        {(_onClose) => {
          return (
            <>
              <ModalHeader>{title}</ModalHeader>
              <ModalBody>
                <div className="form-item">
                  <div className="form-label">游戏名称</div>
                  <div className="form-input">
                    <Input
                      value={form.name}
                      onChange={(e) => {
                        setForm({ ...form, name: e.target.value })
                      }}
                      size="sm"
                      placeholder="请输入游戏名称"
                      style={{
                        width: 300,
                      }}
                    />
                  </div>
                </div>
                <div className="form-item">
                  <div className="form-label">竖屏封面图</div>
                  <div className="form-input">
                    <ImageSelect
                      value={form.cover}
                      onChange={(e) => {
                        setForm({ ...form, cover: e })
                      }}
                      clipAspect={1.3}
                    />
                  </div>
                </div>
                <div className="form-item">
                  <div className="form-label">横屏封面图</div>
                  <div className="form-input">
                    <ImageSelect
                      width={300}
                      value={form.thumb}
                      onChange={(e) => {
                        setForm({ ...form, thumb: e })
                      }}
                      clipAspect={0.6}
                    />
                  </div>
                </div>
                <div className="form-item">
                  <div className="form-label">游戏详情</div>
                  <div className="form-input">
                    <Textarea
                      value={form.description}
                      onChange={(e) => {
                        setForm({ ...form, description: e.target.value })
                      }}
                      placeholder="请输入游戏详情"
                      size="sm"
                      style={{
                        width: 500,
                        height: 200,
                      }}
                    />
                  </div>
                </div>
                <div className="form-item">
                  <div className="form-label">游戏预览</div>
                  <div className="form-input">
                    <div className="preview-box">
                      <input
                        style={{
                          display: 'none',
                        }}
                        type="file"
                        accept="image/*,video/*"
                        multiple={true}
                        ref={previewMultiRef}
                        onChange={(e) => {
                          const files = e.target.files
                          const list = []
                          for (let i = 0; i < files.length; i++) {
                            const file = files[i]
                            if (file.type.startsWith('image')) {
                              list.push({
                                type: 'image',
                                file: file,
                                tmpUrl: URL.createObjectURL(file),
                              })
                            } else if (file.type.startsWith('video')) {
                              list.push({
                                type: 'video',
                                file: file,
                                tmpUrl: URL.createObjectURL(file),
                              })
                            }
                          }
                          setForm({
                            ...form,
                            previeMedia: [...form.previeMedia, ...list] as any,
                          })
                        }}
                      />
                      {form.previeMedia.map((item, index) => {
                        return (
                          <div className="item" key={index}>
                            {item.type === 'image' && (
                              <img src={item.tmpUrl} alt="" />
                            )}
                            {item.type === 'video' && (
                              <video controls src={item.tmpUrl} />
                            )}
                            <div
                              className="remove-icon"
                              onClick={() => {
                                setForm({
                                  ...form,
                                  previeMedia: form.previeMedia.filter(
                                    (_, i) => i !== index
                                  ),
                                })
                              }}>
                              <RemoveSvg />
                            </div>
                          </div>
                        )
                      })}

                      <div
                        className="add-item"
                        onClick={() => {
                          previewMultiRef.current.click()
                        }}>
                        <AddSvg />
                        <span>添加预览图片或视频</span>
                      </div>
                    </div>
                  </div>
                </div>
                <div className="form-item">
                  <div className="form-label">启动模式</div>
                  <div className="form-input">
                    <RadioGroup
                      value={form.openMode}
                      onChange={(e) => {
                        setForm({ ...form, openMode: e })
                      }}
                      options={[
                        {
                          label: '文件打开',
                          value: 'file',
                        },
                        {
                          label: '命令行启动',
                          value: 'cmd',
                        },
                      ]}
                    />
                  </div>
                </div>
                {form.openMode === 'file' && (
                  <div className="form-item">
                    <div className="form-label">启动文件</div>
                    <div className="form-input">
                      <div className="path-select-box">
                        <span
                          className={form.openFilePath ? '' : 'placeholder'}>
                          {form.openFilePath
                            ? form.openFilePath
                            : '请选择启动文件'}
                        </span>
                        <Button
                          color={'primary'}
                          style={{
                            color: 'white',
                            width: 100,
                          }}
                          onPress={async () => {
                            const path = await open({
                              multiple: false,
                              directory: false,
                              filters: [
                                {
                                  name: '可执行文件',
                                  extensions: ['exe', 'bat', 'cmd'],
                                },
                              ],
                            })
                            if (path) {
                              setForm({ ...form, openFilePath: path })
                            }
                          }}
                          size="sm">
                          {form.openFilePath ? '重新选择' : '选择文件'}
                        </Button>
                      </div>
                    </div>
                  </div>
                )}
                {form.openMode === 'cmd' && (
                  <div className="form-item">
                    <div className="form-label">启动命令</div>
                    <div className="form-input">
                      <Input
                        value={form.openCmd}
                        onChange={(e) => {
                          setForm({ ...form, openCmd: e.target.value })
                        }}
                        placeholder="请输入游戏启动命令"
                        size="sm"
                        style={{
                          width: 500,
                        }}
                      />
                    </div>
                  </div>
                )}
              </ModalBody>
              <ModalFooter>
                <Button
                  size="sm"
                  onPress={() => {
                    setForm(defaultForm)
                  }}>
                  清空
                </Button>
                <Button
                  isLoading={loading}
                  size="sm"
                  color="primary"
                  style={{
                    color: 'white',
                  }}
                  onPress={() => {
                    onSubmit()
                  }}>
                  确定
                </Button>
              </ModalFooter>
            </>
          )
        }}
      </ModalContent>
    </Modal>
  )
}

export default forwardRef(AddGameModal)
